`timescale 1ns / 1ps
module testcase ();
    reg rst, clk;
    reg [31:0] pc;
    wire [31:0] pc_in_if;
    wire [31:0] now_inst_in_if;
    wire [31:0] pc_out_id;
    wire [31:0] now_inst_out_id;
    wire [31:0] pc_in_id;
    wire [31:0] now_inst_in_id;
    wire [31:0] pc_out_exe;
    wire [31:0] pc_out_mem;
    wire [31:0] now_inst_out_exe;
    wire [31:0] now_inst_out_mem;

    //译码器输出的控制信号
    wire rf_wr_en;          //寄存器写信号
    wire [1:0] rf_wr_sel;    //寄存器选择信号
    wire [3:0] alu_ctrl;    //运算器的控制信号
    wire [2:0] dm_rd_ctrl;   //数据存储器的读取控制信号
    wire [1:0] dm_wr_ctrl;   //数据存储器的写入控制信号
    wire [31:0] imm_out;    //填充过后的立即数
    wire [31:0] src_a;
    wire [31:0] src_b;
    wire [31:0] reg_r2;
    wire [31:0] reg_r2_out_exe;
    wire [31:0] reg_r2_out_mem;

    wire [31:0] src_out_a;
    wire [31:0] src_out_b;
    wire [3:0] alu_ctrl_out;
    wire [31:0] alu_result;
    wire [31:0] alu_result_out;
    wire [31:0] data_mem_result;
    wire [31:0] alu_inst_bypass;
    wire [31:0] pre_mem_result;
    wire [31:0] pre_mem_inst;
    wire rs_en_out;
    wire rt_en_out;

    wire [2:0] dm_rd_ctrl_out;
    wire [1:0] dm_wr_ctrl_out;
    wire [2:0] dm_rd_ctrl_mem;
    wire [1:0] dm_wr_ctrl_mem;

    wire [31:0] reg_write_data_out;
    wire reg_write_en_out;
    wire [4:0] wb_reg_wr_no;

    wire rf_wr_en_out_exe;
    wire [1:0] rf_wr_sel_out_exe;

    wire rf_wr_en_out_mem;
    wire [1:0] rf_wr_sel_out_mem;
    /**
    *  reg类型的变量不能被接到模块的输出信号上
    **/

    /*iverilog */
    initial
    begin            
        $dumpfile("wave.vcd");        //生成的vcd文件名称
        $dumpvars(0, testcase);     //tb模块名称
    end
    /*iverilog */

    initial begin
        rst = 0;
        clk = 0;
        forever begin
            #10 clk = ~clk;
        end
    end

    initial begin
        #10
        pc = 0;
        forever begin
            #20 pc = pc +1;
        end
    end

    initial
        #2000 $finish;

    //调用其他模块
    instMemory inst1(.clk(clk), .rst(rst), .pc_in(pc), .pc_out(pc_in_if), .now_inst(now_inst_in_if));

    //取指-译码中继器
    IF_ID if_id1(.clk(clk), .rst(rst), .now_inst_in(now_inst_in_if), .pc_in(pc_in_if), .now_inst_out(now_inst_out_id), .pc_out(pc_out_id));

    ID id1(.clk(clk), .rst(rst), .pc_in(pc_out_id), .now_inst(now_inst_out_id), .wb_reg_wr_ctrl(reg_write_en_out), .wb_reg_wr_data(reg_write_data_out), .wb_reg_wr_no(wb_reg_wr_no), .pre_exe_result(alu_result), .pre_exe_inst(alu_inst_bypass), .pre_mem_result(pre_mem_result), .pre_mem_inst(pre_mem_inst), .rf_wr_en(rf_wr_en), .rf_wr_sel(rf_wr_sel), .alu_ctrl(alu_ctrl), .dm_rd_ctrl(dm_rd_ctrl), .dm_wr_ctrl(dm_wr_ctrl), .imm_out(imm_out), .src_a(src_a), .src_b(src_b), .reg_r2(reg_r2), .rs_en_out(rs_en_out), .rt_en_out(rt_en_out));

    //译码-执行中继器
    //ID_EXE id_exe1(.clk(clk), .rst(rst), .func_in(alu_ctrl), .srcA_in(src_a), .srcB_in(src_b), .dm_rd_ctrl_in(dm_rd_ctrl), .dm_wr_ctrl_in(dm_wr_ctrl), .pc_in(pc_out_id), .now_inst_in(now_inst_out_id) .func_out(alu_ctrl_out), .srcA_out(src_out_a), .srcB_out(src_out_b), .dm_rd_ctrl_out(dm_rd_ctrl_out), .dm_wr_ctrl_out(dm_wr_ctrl_out), .pc_out(pc_out_exe), .now_inst_out(now_inst_out_exe));
    ID_EXE id_exe1(.clk(clk), .rst(rst), .func_in(alu_ctrl), .srcA_in(src_a), .srcB_in(src_b), .reg_write_en_in(rf_wr_en), .reg_write_sel_in(rf_wr_sel), .dm_rd_ctrl_in(dm_rd_ctrl), .dm_wr_ctrl_in(dm_wr_ctrl), .pc_in(pc_out_id), .now_inst_in(now_inst_out_id), .reg_r2_in(reg_r2), .func_out(alu_ctrl_out), .srcA_out(src_out_a), .srcB_out(src_out_b), .reg_write_en_out(rf_wr_en_out_exe), .reg_write_sel_out(rf_wr_sel_out_exe), .dm_rd_ctrl_out(dm_rd_ctrl_out), .dm_wr_ctrl_out(dm_wr_ctrl_out), .pc_out(pc_out_exe), .now_inst_out(now_inst_out_exe), .reg_r2_out(reg_r2_out_exe));

    alu a1(.clk(clk), .rst(rst), .srcA(src_out_a), .srcB(src_out_b), .func(alu_ctrl_out), .now_inst(now_inst_out_exe), .result(alu_result), .alu_inst_out(alu_inst_bypass));

    //执行-访存中继器
    EXE_MEM exe_mem1(.clk(clk), .rst(rst), .alu_r_in(alu_result), .dm_rd_ctrl_in(dm_rd_ctrl_out), .dm_wr_ctrl_in(dm_wr_ctrl_out), .reg_write_en_in(rf_wr_en_out_exe), .reg_write_sel_in(rf_wr_sel_out_exe), .now_inst_in(now_inst_out_exe), .pc_in(pc_out_exe), .reg_r2_in(reg_r2_out_exe), .alu_r_out(alu_result_out), .dm_rd_ctrl_out(dm_rd_ctrl_mem), .dm_wr_ctrl_out(dm_wr_ctrl_mem), .reg_write_en_out(rf_wr_en_out_mem), .reg_write_sel_out(rf_wr_sel_out_mem), .now_inst_out(now_inst_out_mem), .pc_out(pc_out_mem), .reg_r2_out(reg_r2_out_mem));

    dataMemory data1(.clk(clk), .now_inst(now_inst_out_mem), .dm_rd_ctrl(dm_rd_ctrl_out), .dm_wr_ctrl(dm_wr_ctrl_out), .dm_addr(alu_result_out), .dm_din(reg_r2_out_mem), .dm_dout(data_mem_result), .dm_inst_out(pre_mem_inst), .dm_exe_result_out(pre_mem_result));

    //访存-写回中继器
    MEM_WB mem_wb1(.clk(clk), .rst(rst), .reg_write_en_in(rf_wr_en_out_mem), .reg_wr_sel_in(rf_wr_sel_out_mem), .alu_result_in(alu_result_out), .mem_result_in(data_mem_result), .pc_in(pc_out_mem), .inst_in(now_inst_out_mem), .reg_write_en_out(reg_write_en_out), .reg_write_data_out(reg_write_data_out), .reg_write_no_out(wb_reg_wr_no));
endmodule